'    Copyright 2008 Jan Molnar <jan.molnar@abds.de>
'
'    This file is part of JCQ.

'    JCQ is free software: you can redistribute it and/or modify
'    it under the terms of the GNU General Public License as published by
'    the Free Software Foundation, either version 2 of the License, or
'    (at your option) any later version.

'    JCQ is distributed in the hope that it will be useful,
'    but WITHOUT ANY WARRANTY; without even the implied warranty of
'    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
'    GNU General Public License for more details.

'    You should have received a copy of the GNU General Public License
'    along with JCQ. If not, see <http://www.gnu.org/licenses/>.

Imports System.Xml

Public Class DefaultIListReferenceFormatter
    Inherits DefaultReferenceFormatter

    Public Sub New(ByVal context As ISerializer, ByVal listType As Type)
        MyBase.New(context, listType, False, False)
    End Sub

    Public Overrides Sub Serialize(ByVal graph As Object, ByVal writer As System.Xml.XmlWriter)
        writer.WriteStartElement("list")

        WriteIdAttribute(graph, writer)
        WriteTypeAttribute(graph, writer)

        SerializeItems(DirectCast(graph, Collections.IList), writer)

        writer.WriteEndElement()
    End Sub

    Public Overrides Function Deserialize(ByVal reader As System.Xml.XmlReader) As Object
        Dim objectId As Integer
        Dim type As Type
        Dim obj As IList

        reader.MoveToFirstAttribute() ' This is always __id
        objectId = GetObjectId(reader)

        reader.MoveToNextAttribute() ' This is always __type
        type = GetObjectType(reader)

        obj = DirectCast(CreateObject(type, reader), IList)

        If Not reader.IsEmptyElement Then
            DeserializeItems(obj, reader)
        End If

        Serializer.RegisterObject(objectId, obj)

        Return obj
    End Function

    Protected Overridable Sub DeserializeItems(ByVal list As IList, ByVal reader As XmlReader)
        If reader.IsEmptyElement Then Return

        Dim type As Type
        Dim value As String

        Do While reader.Read() AndAlso reader.NodeType = XmlNodeType.Element
            reader.MoveToFirstAttribute() ' This is always __type
            type = GetObjectType(reader)

            reader.MoveToNextAttribute() ' This is always __value
            value = GetObjectValue(reader)

            If type.IsValueType Then
                ' Value Type
                Dim formatter As IValueFormatter = Serializer.GetValueFormatter(type)

                list.Add(formatter.Deserialize(value))
            ElseIf type Is GetType(String) Then
                ' String
                list.Add(value)
            Else
                ' Reference Type
                Dim ref As ListItemFixUp = New ListItemFixUp(Integer.Parse(value), list)

                Serializer.RegisterListItemFixUp(ref)
            End If
        Loop
    End Sub

    Protected Overridable Sub SerializeItems(ByVal list As IList, ByVal writer As XmlWriter)
        For Each x As Object In list
            Dim itemType As Type = x.GetType
            Dim itemValue As String

            writer.WriteStartElement("item")
            WriteTypeAttribute(x, x.GetType, writer)

            If itemType.IsValueType Then
                Dim formatter As IValueFormatter = Serializer.GetValueFormatter(itemType)
                itemValue = formatter.Serialize(x)
            ElseIf itemType Is GetType(String) Then
                itemValue = DirectCast(x, String)
            Else
                itemValue = Serializer.GetSerializeObjectId(x).ToString
            End If

            WriteValueAttribute(x, itemValue, writer)

            writer.WriteEndElement()
        Next
    End Sub
End Class